using System;
using System.Globalization;
using Reflector.CodeModel;
using System.Collections.Generic;
namespace Reflector.CodeDom
{
    /// <summary>
    /// 
    /// </summary>
    public class Visitor
    {
        // Methods
        /// <summary>
        /// Visits the address dereference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAddressDereferenceExpression(IAddressDereferenceExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        protected Stack<CodeStackItem> codeStack;
        /// <summary>
        /// Visits the address of expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAddressOfExpression(IAddressOfExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the address out expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAddressOutExpression(IAddressOutExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the address reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAddressReferenceExpression(IAddressReferenceExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the anonymous method expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAnonymousMethodExpression(IAnonymousMethodExpression value)
        {
            if (value != null)
            {
                VisitType(value.DelegateType);
                VisitParameterDeclarationCollection(value.Parameters);
                VisitMethodReturnType(value.ReturnType);
                VisitStatement(value.Body);
            }
        }

        /// <summary>
        /// Visits the argument list expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArgumentListExpression(IArgumentListExpression value)
        {
        }

        /// <summary>
        /// Visits the argument reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArgumentReferenceExpression(IArgumentReferenceExpression value)
        {
        }

        /// <summary>
        /// Visits the array create expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArrayCreateExpression(IArrayCreateExpression value)
        {
            if (value != null)
            {
                VisitType(value.Type);
                VisitExpression(value.Initializer);
                VisitExpressionCollection(value.Dimensions);
            }
        }
        /// <summary>
        /// Visits the array dimension.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArrayDimension(IArrayDimension value)
        {
        }

        /// <summary>
        /// Visits the array dimension collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArrayDimensionCollection(IArrayDimensionCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitArrayDimension(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the array indexer expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArrayIndexerExpression(IArrayIndexerExpression value)
        {
            if (value != null)
            {
                VisitExpressionCollection(value.Indices);
                VisitExpression(value.Target);
            }
        }

        /// <summary>
        /// Visits the type of the array.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitArrayType(IArrayType value)
        {
            VisitType(value.ElementType);
            VisitArrayDimensionCollection(value.Dimensions);
        }

        /// <summary>
        /// Visits the assembly.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAssembly(IAssembly value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);
                VisitModuleCollection(value.Modules);
            }
        }

        /// <summary>
        /// Visits the assembly reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAssemblyReference(IAssemblyReference value)
        {
        }

        /// <summary>
        /// Visits the assign expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAssignExpression(IAssignExpression value)
        {
            if (value != null)
            {
                VisitExpression(value.Target);
                VisitExpression(value.Expression);
            }
        }

        /// <summary>
        /// Visits the attach event statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitAttachEventStatement(IAttachEventStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Event);
                VisitExpression(value.Listener);
            }
        }
        /// <summary>
        /// Visits the base reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitBaseReferenceExpression(IBaseReferenceExpression value)
        {
        }

        /// <summary>
        /// Visits the binary expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitBinaryExpression(IBinaryExpression value)
        {
            if (value != null)
            {
                VisitExpression(value.Left);
                VisitExpression(value.Right);
            }
        }

        /// <summary>
        /// Visits the block expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitBlockExpression(IBlockExpression value)
        {
            if (value != null)

                VisitExpressionCollection(value.Expressions);
        }

        /// <summary>
        /// Visits the block statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitBlockStatement(IBlockStatement value)
        {
            if (value != null)

                VisitStatementCollection(value.Statements);
        }

        /// <summary>
        /// Visits the break statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitBreakStatement(IBreakStatement value)
        {
        }

        /// <summary>
        /// Visits the can cast expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitCanCastExpression(ICanCastExpression value)
        {
            if (value != null)
            {
                VisitType(value.TargetType);
                VisitExpression(value.Expression);
            }
        }

        /// <summary>
        /// Visits the cast expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitCastExpression(ICastExpression value)
        {
            if (value != null)
            {
                VisitType(value.TargetType);
                VisitExpression(value.Expression);
            }
        }
        /// <summary>
        /// Visits the catch clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitCatchClause(ICatchClause value)
        {
            if (value != null)
            {
                VisitVariableDeclaration(value.Variable);
                VisitExpression(value.Condition);
                VisitStatement(value.Body);
            }
        }
        /// <summary>
        /// Visits the catch clause collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitCatchClauseCollection(ICatchClauseCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitCatchClause(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the comment statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitCommentStatement(ICommentStatement value)
        {
        }

        /// <summary>
        /// Visits the condition case.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitConditionCase(IConditionCase value)
        {
            if (value != null)
            {
                VisitExpression(value.Condition);
                VisitStatement(value.Body);
            }
        }

        /// <summary>
        /// Visits the condition expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitConditionExpression(IConditionExpression value)
        {
            if (value != null)
            {
                VisitExpression(value.Condition);
                VisitExpression(value.Then);
                VisitExpression(value.Else);
            }
        }
        /// <summary>
        /// Visits the condition statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitConditionStatement(IConditionStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Condition);
                VisitStatement(value.Then);
                VisitStatement(value.Else);
            }
        }
        /// <summary>
        /// Visits the continue statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitContinueStatement(IContinueStatement value)
        {
        }

        /// <summary>
        /// Visits the custom attribute.
        /// </summary>
        /// <param name="customAttribute">The custom attribute.</param>
        public virtual void VisitCustomAttribute(ICustomAttribute customAttribute)
        {
            if (customAttribute != null)

                VisitExpressionCollection(customAttribute.Arguments);
        }

        /// <summary>
        /// Visits the custom attribute collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitCustomAttributeCollection(ICustomAttributeCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitCustomAttribute(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the debug break statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitDebugBreakStatement(IDebugBreakStatement value)
        {
        }

        /// <summary>
        /// Visits the default case.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitDefaultCase(IDefaultCase value)
        {
            if (value != null)

                VisitStatement(value.Body);
        }

        /// <summary>
        /// Visits the delegate create expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitDelegateCreateExpression(IDelegateCreateExpression value)
        {
            if (value != null)
            {
                VisitType(value.DelegateType);
                VisitExpression(value.Target);
            }
        }

        /// <summary>
        /// Visits the delegate invoke expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitDelegateInvokeExpression(IDelegateInvokeExpression value)
        {
            if (value != null)
            {
                VisitExpressionCollection(value.Arguments);
                VisitExpression(value.Target);
            }
        }

        /// <summary>
        /// Visits the do statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitDoStatement(IDoStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Condition);
                VisitStatement(value.Body);
            }
        }

        /// <summary>
        /// Visits the embedded resource.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitEmbeddedResource(IEmbeddedResource value)
        {
        }

        /// <summary>
        /// Visits the event declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitEventDeclaration(IEventDeclaration value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);
                VisitType(value.EventType);
            }
        }

        /// <summary>
        /// Visits the event declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitEventDeclarationCollection(IEventDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitEventDeclaration(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the event reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitEventReference(IEventReference value)
        {
            if (value != null)

                VisitType(value.EventType);
        }

        /// <summary>
        /// Visits the event reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitEventReferenceExpression(IEventReferenceExpression value)
        {
            if (value != null)
            {
                VisitEventReference(value.Event);
                VisitExpression(value.Target);
            }
        }
        /// <summary>
        /// Visits the expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public void VisitExpression(IExpression value)
        {
            if (value != null)
            {
                VisitAddressDereferenceExpression(value as IAddressDereferenceExpression);
                VisitAddressOfExpression(value as IAddressOfExpression);
                VisitAddressOutExpression(value as IAddressOutExpression);
                VisitAddressReferenceExpression(value as IAddressReferenceExpression);
                VisitAnonymousMethodExpression(value as IAnonymousMethodExpression);
                VisitArgumentListExpression(value as IArgumentListExpression);
                VisitArgumentReferenceExpression(value as IArgumentReferenceExpression);
                VisitArrayCreateExpression(value as IArrayCreateExpression);
                VisitArrayIndexerExpression(value as IArrayIndexerExpression);
                VisitAssignExpression(value as IAssignExpression);
                VisitBaseReferenceExpression(value as IBaseReferenceExpression);
                VisitBinaryExpression(value as IBinaryExpression);
                VisitBlockExpression(value as IBlockExpression);
                VisitCanCastExpression(value as ICanCastExpression);
                VisitCastExpression(value as ICastExpression);
                VisitConditionExpression(value as IConditionExpression);
                VisitDelegateCreateExpression(value as IDelegateCreateExpression);
                VisitDelegateInvokeExpression(value as IDelegateInvokeExpression);
                VisitEventReferenceExpression(value as IEventReferenceExpression);
                VisitExpressionCollection(value as IExpressionCollection);
                VisitExpressionStatement(value as IExpressionStatement);
                VisitFieldOfExpression(value as IFieldOfExpression);
                VisitFieldReferenceExpression(value as IFieldReferenceExpression);
                VisitGenericDefaultExpression(value as IGenericDefaultExpression);
                VisitLambdaExpression(value as ILambdaExpression);
                VisitLiteralExpression(value as ILiteralExpression);
                VisitMemberInitializerExpression(value as IMemberInitializerExpression);
                VisitMethodInvokeExpression(value as IMethodInvokeExpression);
                VisitMethodOfExpression(value as IMethodOfExpression);
                VisitMethodReferenceExpression(value as IMethodReferenceExpression);
                VisitNullCoalescingExpression(value as INullCoalescingExpression);
                VisitObjectCreateExpression(value as IObjectCreateExpression);
                VisitPropertyIndexerExpression(value as IPropertyIndexerExpression);
                VisitPropertyReferenceExpression(value as IPropertyReferenceExpression);
                VisitQueryExpression(value as IQueryExpression);
                VisitSizeOfExpression(value as ISizeOfExpression);
                VisitSnippetExpression(value as ISnippetExpression);
                VisitStackAllocateExpression(value as IStackAllocateExpression);
                VisitThisReferenceExpression(value as IThisReferenceExpression);
                VisitTryCastExpression(value as ITryCastExpression);
                VisitTypedReferenceCreateExpression(value as ITypedReferenceCreateExpression);
                VisitTypeOfExpression(value as ITypeOfExpression);
                VisitTypeOfTypedReferenceExpression(value as ITypeOfTypedReferenceExpression);
                VisitTypeReferenceExpression(value as ITypeReferenceExpression);
                VisitUnaryExpression(value as IUnaryExpression);
                VisitValueOfTypedReferenceExpression(value as IValueOfTypedReferenceExpression);
                VisitVariableDeclarationExpression(value as IVariableDeclarationExpression);
                VisitVariableReferenceExpression(value as IVariableReferenceExpression);
            }
        }

        /// <summary>
        /// Visits the expression collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitExpressionCollection(IExpressionCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitExpression(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the expression statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitExpressionStatement(IExpressionStatement value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the field declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFieldDeclaration(IFieldDeclaration value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);

                VisitType(value.FieldType);
            }
        }

        /// <summary>
        /// Visits the field declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFieldDeclarationCollection(IFieldDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitFieldDeclaration(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the field of expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFieldOfExpression(IFieldOfExpression value)
        {
            if (value != null)

                VisitFieldReference(value.Field);
        }

        /// <summary>
        /// Visits the field reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFieldReference(IFieldReference value)
        {
            if (value != null)

                VisitType(value.FieldType);
        }

        /// <summary>
        /// Visits the field reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFieldReferenceExpression(IFieldReferenceExpression value)
        {
            if (value != null)
            {
                VisitFieldReference(value.Field);
                VisitExpression(value.Target);
            }
        }

        /// <summary>
        /// Visits the file resource.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFileResource(IFileResource value)
        {
        }

        /// <summary>
        /// Visits the fixed statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFixedStatement(IFixedStatement value)
        {
            if (value != null)
            {
                VisitVariableDeclaration(value.Variable);
                VisitExpression(value.Expression);
                VisitStatement(value.Body);
            }
        }

        /// <summary>
        /// Visits for each statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitForEachStatement(IForEachStatement value)
        {
            if (value != null)
            {
                VisitVariableDeclaration(value.Variable);
                VisitExpression(value.Expression);
                VisitStatement(value.Body);
            }
        }
        /// <summary>
        /// Visits for statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitForStatement(IForStatement value)
        {
            if (value != null)
            {
                VisitStatement(value.Initializer);
                VisitExpression(value.Condition);
                VisitStatement(value.Increment);
                VisitStatement(value.Body);
            }
        }
        /// <summary>
        /// Visits from clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitFromClause(IFromClause value)
        {
            if (value != null)
            {
                VisitVariableDeclaration(value.Variable);
                VisitExpression(value.Expression);
            }
        }
        /// <summary>
        /// Visits the function pointer.
        /// </summary>
        /// <param name="type">The type.</param>
        public virtual void VisitFunctionPointer(IFunctionPointer type)
        {
        }

        /// <summary>
        /// Visits the generic argument.
        /// </summary>
        /// <param name="type">The type.</param>
        public virtual void VisitGenericArgument(IGenericArgument type)
        {
        }

        /// <summary>
        /// Visits the generic default expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitGenericDefaultExpression(IGenericDefaultExpression value)
        {
        }

        /// <summary>
        /// Visits the generic parameter.
        /// </summary>
        /// <param name="type">The type.</param>
        public virtual void VisitGenericParameter(IGenericParameter type)
        {
        }

        /// <summary>
        /// Visits the goto statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitGotoStatement(IGotoStatement value)
        {
        }

        /// <summary>
        /// Visits the group operation.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitGroupOperation(IGroupOperation value)
        {
            if (value != null)
            {
                VisitExpression(value.Item);
                VisitExpression(value.Key);
            }
        }
        /// <summary>
        /// Visits the join clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitJoinClause(IJoinClause value)
        {
            if (value != null)
            {
                VisitVariableDeclaration(value.Variable);
                VisitExpression(value.In);
                VisitExpression(value.On);
                VisitExpression(value.Equality);
                if (value.Into != null)
                {
                    VisitVariableDeclaration(value.Into);
                }
            }
        }

        /// <summary>
        /// Visits the labeled statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitLabeledStatement(ILabeledStatement value)
        {
            if (value != null)

                VisitStatement(value.Statement);
        }

        /// <summary>
        /// Visits the lambda expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitLambdaExpression(ILambdaExpression value)
        {
            if (value != null)
            {
                VisitVariableDeclarationCollection(value.Parameters);
                VisitExpression(value.Body);
            }
        }

        /// <summary>
        /// Visits the let clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitLetClause(ILetClause value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the literal expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitLiteralExpression(ILiteralExpression value)
        {
        }

        /// <summary>
        /// Visits the lock statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitLockStatement(ILockStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Expression);
                VisitStatement(value.Body);
            }
        }
        /// <summary>
        /// Visits the member initializer expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMemberInitializerExpression(IMemberInitializerExpression value)
        {
            if (value != null)

                VisitExpression(value.Value);
        }

        /// <summary>
        /// Visits the memory copy statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMemoryCopyStatement(IMemoryCopyStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Source);
                VisitExpression(value.Destination);
                VisitExpression(value.Length);
            }
        }
        /// <summary>
        /// Visits the memory initialize statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMemoryInitializeStatement(IMemoryInitializeStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Offset);
                VisitExpression(value.Value);
                VisitExpression(value.Length);
            }
        }

        /// <summary>
        /// Visits the method declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodDeclaration(IMethodDeclaration value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);
                VisitParameterDeclarationCollection(value.Parameters);
                VisitMethodReferenceCollection(value.Overrides);
                VisitMethodReturnType(value.ReturnType);
                IBlockStatement body = value.Body as IBlockStatement;
                if (body != null)
                {
                    VisitStatement(body);
                }
            }
        }

        /// <summary>
        /// Visits the method declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodDeclarationCollection(IMethodDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitMethodDeclaration(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the method invoke expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodInvokeExpression(IMethodInvokeExpression value)
        {
            if (value != null)
            {
                VisitExpressionCollection(value.Arguments);
                VisitExpression(value.Method);
            }
        }
        /// <summary>
        /// Visits the method of expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodOfExpression(IMethodOfExpression value)
        {
            if (value != null)
            {
                VisitMethodReference(value.Method, true);
                if (value.Type != null)
                {
                    VisitTypeReference(value.Type);
                }
            }
        }
        /// <summary>
        /// Visits the method reference.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="processParameters">if set to <c>true</c> [process parameters].</param>
        public virtual void VisitMethodReference(IMethodReference value, bool processParameters)
        {
            if (value != null)

                VisitMethodReturnType(value.ReturnType);
        }

        /// <summary>
        /// Visits the method reference collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodReferenceCollection(IMethodReferenceCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitMethodReference(value[i], true);
                }
            }
        }
        /// <summary>
        /// Visits the method reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodReferenceExpression(IMethodReferenceExpression value)
        {
            if (value != null)

                VisitExpression(value.Target);
        }

        /// <summary>
        /// Visits the method return statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodReturnStatement(IMethodReturnStatement value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the type of the method return.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitMethodReturnType(IMethodReturnType value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);
                VisitType(value.Type);
            }
        }
        /// <summary>
        /// Visits the module.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitModule(IModule value)
        {
            if (value != null)

                VisitCustomAttributeCollection(value.Attributes);
        }

        /// <summary>
        /// Visits the module collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitModuleCollection(IModuleCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitModule(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the module reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitModuleReference(IModuleReference value)
        {
        }

        /// <summary>
        /// Visits the namespace.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitNamespace(INamespace value)
        {
            if (value != null)

                VisitTypeDeclarationCollection(value.Types);
        }

        /// <summary>
        /// Visits the null coalescing expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitNullCoalescingExpression(INullCoalescingExpression value)
        {
            if (value != null)
            {
                VisitExpression(value.Condition);
                VisitExpression(value.Expression);
            }
        }

        /// <summary>
        /// Visits the object create expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitObjectCreateExpression(IObjectCreateExpression value)
        {
            if (value != null)
            {
                VisitType(value.Type);
                if (value.Constructor != null)
                {
                    VisitMethodReference(value.Constructor, true);
                }
                VisitExpressionCollection(value.Arguments);
                if (value.Initializer != null)
                {
                    VisitBlockExpression(value.Initializer);
                }
            }
        }
        /// <summary>
        /// Visits the optional modifier.
        /// </summary>
        /// <param name="type">The type.</param>
        public virtual void VisitOptionalModifier(IOptionalModifier type)
        {
            if (type != null)
            {
                VisitType(type.Modifier);
                VisitType(type.ElementType);
            }
        }

        /// <summary>
        /// Visits the order clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitOrderClause(IOrderClause value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the parameter declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitParameterDeclaration(IParameterDeclaration value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);
                VisitType(value.ParameterType);
            }
        }
        /// <summary>
        /// Visits the parameter declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitParameterDeclarationCollection(IParameterDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitParameterDeclaration(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the type of the pointer.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitPointerType(IPointerType value)
        {
            if (value != null)

                VisitType(value.ElementType);
        }

        /// <summary>
        /// Visits the property declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitPropertyDeclaration(IPropertyDeclaration value)
        {
            VisitCustomAttributeCollection(value.Attributes);
            VisitType(value.PropertyType);
        }

        /// <summary>
        /// Visits the property declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitPropertyDeclarationCollection(IPropertyDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitPropertyDeclaration(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the property indexer expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitPropertyIndexerExpression(IPropertyIndexerExpression value)
        {
            if (value != null)
            {
                VisitExpressionCollection(value.Indices);
                VisitExpression(value.Target);
            }
        }
        /// <summary>
        /// Visits the property reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitPropertyReference(IPropertyReference value)
        {
            if (value != null)

                VisitType(value.PropertyType);
        }

        /// <summary>
        /// Visits the property reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitPropertyReferenceExpression(IPropertyReferenceExpression value)
        {
            if (value != null)
            {
                VisitPropertyReference(value.Property);
                VisitExpression(value.Target);
            }
        }

        /// <summary>
        /// Visits the query body.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitQueryBody(IQueryBody value)
        {
            if (value != null)
            {
                VisitQueryOperation(value.Operation);
                VisitQueryClauseCollection(value.Clauses);
                if (value.Continuation != null)
                {
                    VisitQueryContinuation(value.Continuation);
                }
            }
        }
        /// <summary>
        /// Visits the query clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitQueryClause(IQueryClause value)
        {
            if (value != null)
            {
                VisitFromClause(value as IFromClause);
                VisitWhereClause(value as IWhereClause);
                VisitLetClause(value as ILetClause);
                VisitJoinClause(value as IJoinClause);
                VisitOrderClause(value as IOrderClause);
            }
        }
        /// <summary>
        /// Visits the query clause collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitQueryClauseCollection(IQueryClauseCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitQueryClause(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the query continuation.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitQueryContinuation(IQueryContinuation value)
        {
            if (value != null)
            {
                VisitVariableDeclaration(value.Variable);
                VisitQueryBody(value.Body);
            }
        }
        /// <summary>
        /// Visits the query expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitQueryExpression(IQueryExpression value)
        {
            if (value != null)
            {
                VisitFromClause(value.From);
                VisitQueryBody(value.Body);
            }
        }
        /// <summary>
        /// Visits the query operation.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitQueryOperation(IQueryOperation value)
        {
            if (value != null)
            {
                if (value is ISelectOperation)
                {
                    VisitSelectOperation(value as ISelectOperation);
                }
                else
                {
                    if (!(value is IGroupOperation))
                    {
                        throw new NotSupportedException();
                    }
                    VisitGroupOperation(value as IGroupOperation);
                }
            }
        }
        /// <summary>
        /// Visits the type of the reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitReferenceType(IReferenceType value)
        {
            if (value != null)

                VisitType(value.ElementType);
        }

        /// <summary>
        /// Visits the remove event statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitRemoveEventStatement(IRemoveEventStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Event);
                VisitExpression(value.Listener);
            }
        }

        /// <summary>
        /// Visits the required modifier.
        /// </summary>
        /// <param name="type">The type.</param>
        public virtual void VisitRequiredModifier(IRequiredModifier type)
        {
            if (type != null)
            {
                VisitType(type.Modifier);
                VisitType(type.ElementType);
            }
        }
        /// <summary>
        /// Visits the resource.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitResource(IResource value)
        {
            if (value != null)
            {
                IEmbeddedResource resource = value as IEmbeddedResource;
                if (resource != null)
                {
                    VisitEmbeddedResource(resource);
                }
                IFileResource resource2 = value as IFileResource;
                if (resource2 != null)
                {
                    VisitFileResource(resource2);
                }
            }
        }
        /// <summary>
        /// Visits the resource collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitResourceCollection(IResourceCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitResource(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the select operation.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitSelectOperation(ISelectOperation value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the size of expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitSizeOfExpression(ISizeOfExpression value)
        {
            if (value != null)

                VisitType(value.Type);
        }

        /// <summary>
        /// Visits the snippet expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitSnippetExpression(ISnippetExpression value)
        {
        }

        /// <summary>
        /// Visits the stack allocate expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitStackAllocateExpression(IStackAllocateExpression value)
        {
            if (value != null)
            {
                VisitType(value.Type);
                VisitExpression(value.Expression);
            }
        }
        /// <summary>
        /// Visits the statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitStatement(IStatement value)
        {
            if (value != null)
            {
                VisitLabeledStatement(value as ILabeledStatement);
                VisitWhileStatement(value as IWhileStatement);
                VisitAttachEventStatement(value as IAttachEventStatement);
                VisitContinueStatement(value as IContinueStatement);
                VisitLockStatement(value as ILockStatement);
                VisitDebugBreakStatement(value as IDebugBreakStatement);
                VisitMemoryInitializeStatement(value as IMemoryInitializeStatement);
                VisitMemoryCopyStatement(value as IMemoryCopyStatement);
                VisitFixedStatement(value as IFixedStatement);
                VisitUsingStatement(value as IUsingStatement);
                VisitCommentStatement(value as ICommentStatement);
                VisitBreakStatement(value as IBreakStatement);
                VisitSwitchStatement(value as ISwitchStatement);
                VisitRemoveEventStatement(value as IRemoveEventStatement);
                VisitThrowExceptionStatement(value as IThrowExceptionStatement);
                VisitTryCatchFinallyStatement(value as ITryCatchFinallyStatement);
                VisitDoStatement(value as IDoStatement);
                VisitForEachStatement(value as IForEachStatement);
                VisitForStatement(value as IForStatement);
                VisitGotoStatement(value as IGotoStatement);
                VisitMethodReturnStatement(value as IMethodReturnStatement);
                VisitConditionStatement(value as IConditionStatement);
                VisitBlockStatement(value as IBlockStatement);
                VisitExpressionStatement(value as IExpressionStatement);
            }
        }
        /// <summary>
        /// Visits the statement collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitStatementCollection(IStatementCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitStatement(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the switch case.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitSwitchCase(ISwitchCase value)
        {

            if (value != null)
            {
                IConditionCase conditionCase = value as IConditionCase;
                if (conditionCase == null)
                {
                    IDefaultCase defaultCase = value as IDefaultCase;
                    if (defaultCase == null)
                    {
                        throw new NotSupportedException
                            (string.Format(CultureInfo.InvariantCulture,
                                        "Invalid switch case type '{0}'.",
                                        new object[] { value.GetType().Name }));
                    }
                    VisitDefaultCase(defaultCase);
                }
                else
                {
                    VisitConditionCase(conditionCase);
                }
            }
        }

        /// <summary>
        /// Visits the switch case collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitSwitchCaseCollection(ISwitchCaseCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitSwitchCase(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the switch statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitSwitchStatement(ISwitchStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Expression);
                VisitSwitchCaseCollection(value.Cases);
            }
        }

        /// <summary>
        /// Visits the this reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitThisReferenceExpression(IThisReferenceExpression value)
        {
        }

        /// <summary>
        /// Visits the throw exception statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitThrowExceptionStatement(IThrowExceptionStatement value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the try cast expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTryCastExpression(ITryCastExpression value)
        {
            if (value != null)
            {
                VisitType(value.TargetType);
                VisitExpression(value.Expression);
            }
        }
        /// <summary>
        /// Visits the try catch finally statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTryCatchFinallyStatement(ITryCatchFinallyStatement value)
        {
            if (value != null)
            {

                VisitCatchClauseCollection(value.CatchClauses);
                VisitStatement(value.Finally);
                VisitStatement(value.Fault);
            }
        }
        /// <summary>
        /// Visits the type.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitType(IType value)
        {
            if (value != null)
            {
                VisitGenericArgument(value as IGenericArgument);
                VisitGenericParameter(value as IGenericParameter);
                VisitFunctionPointer(value as IFunctionPointer);
                VisitRequiredModifier(value as IRequiredModifier);
                VisitOptionalModifier(value as IOptionalModifier);
                VisitReferenceType(value as IReferenceType);
                VisitPointerType(value as IPointerType);
                VisitArrayType(value as IArrayType);
                VisitTypeReference(value as ITypeReference);
            }
        }


        /// <summary>
        /// Visits the type collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeCollection(ITypeCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitType(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the type declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeDeclaration(ITypeDeclaration value)
        {
            if (value != null)
            {
                VisitCustomAttributeCollection(value.Attributes);
                VisitMethodDeclarationCollection(value.Methods);
                VisitFieldDeclarationCollection(value.Fields);
                VisitPropertyDeclarationCollection(value.Properties);
                VisitEventDeclarationCollection(value.Events);
                VisitTypeDeclarationCollection(value.NestedTypes);
            }
        }
        /// <summary>
        /// Visits the type declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeDeclarationCollection(ITypeDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitTypeDeclaration(value[i]);
                }
            }
        }

        /// <summary>
        /// Visits the typed reference create expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypedReferenceCreateExpression(ITypedReferenceCreateExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the type of expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeOfExpression(ITypeOfExpression value)
        {
            if (value != null)

                VisitType(value.Type);
        }

        /// <summary>
        /// Visits the type of typed reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeOfTypedReferenceExpression(ITypeOfTypedReferenceExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the type reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeReference(ITypeReference value)
        {
            if (value != null)

                VisitTypeCollection(value.GenericArguments);
        }

        /// <summary>
        /// Visits the type reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitTypeReferenceExpression(ITypeReferenceExpression value)
        {
            if (value != null)

                VisitType(value.Type);
        }

        /// <summary>
        /// Visits the unary expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitUnaryExpression(IUnaryExpression value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the using statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitUsingStatement(IUsingStatement value)
        {
            if (value != null)
            {

                VisitExpression(value.Expression);
                VisitStatement(value.Body);
            }
        }
        /// <summary>
        /// Visits the value of typed reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitValueOfTypedReferenceExpression(IValueOfTypedReferenceExpression value)
        {
            if (value != null)
            {
                VisitType(value.TargetType);
                VisitExpression(value.Expression);
            }
        }
        /// <summary>
        /// Visits the variable declaration.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitVariableDeclaration(IVariableDeclaration value)
        {
            if (value != null)

                VisitType(value.VariableType);
        }

        /// <summary>
        /// Visits the variable declaration collection.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitVariableDeclarationCollection(IVariableDeclarationCollection value)
        {
            if (value != null)
            {
                for (int i = 0; i < value.Count; i++)
                {
                    VisitVariableDeclaration(value[i]);
                }
            }
        }
        /// <summary>
        /// Visits the variable declaration expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitVariableDeclarationExpression(IVariableDeclarationExpression value)
        {
            if (value != null)

                VisitVariableDeclaration(value.Variable);
        }

        /// <summary>
        /// Visits the variable reference.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitVariableReference(IVariableReference value)
        {
        }

        /// <summary>
        /// Visits the variable reference expression.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression value)
        {
            if (value != null)

                VisitVariableReference(value.Variable);
        }

        /// <summary>
        /// Visits the where clause.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitWhereClause(IWhereClause value)
        {
            if (value != null)

                VisitExpression(value.Expression);
        }

        /// <summary>
        /// Visits the while statement.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void VisitWhileStatement(IWhileStatement value)
        {
            if (value != null)
            {
                VisitExpression(value.Condition);
                VisitStatement(value.Body);
            }
        }
        /// <summary>
        /// Gets the method target.
        /// </summary>
        /// <value></value>
        public CodeStackItem MethodTarget
        {
            get
            {
                CodeStackItem returnValue = null;
                if (codeStack.Count > 0)
                {
                    returnValue = codeStack.Peek();
                }
                else
                    throw new System.Exception("No code items in the stack");
                return returnValue;
            }
        }
    }
}